import os
import logging
from os import environ
import wsgiref.handlers
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
from google.appengine.ext import db
from google.appengine.api import mail
import datetime
import textwrap

class Person(db.Model):
    date = db.DateTimeProperty(auto_now_add=True)
    user = db.UserProperty()
    address = db.EmailProperty()
    skillName = db.StringProperty()
    realName =  db.StringProperty()
    activity =  db.StringProperty(default='programming')
    whoami =  db.StringProperty(default="I make simple communication applications.")
    title =  db.StringProperty(default="How's my code?")
    purpose =  db.StringProperty(default="To see how I can improve my apps.")
    moreinfo =  db.StringProperty(default="Please be nice. I will, too.")
    replyinfo =  db.StringProperty(default="Usually within a day.")
    image = db.BlobProperty(default='')
    imagecaption = db.StringProperty(default='')
    attachment = db.BlobProperty(default='')
    stopDate = db.DateProperty(default=datetime.date(2009,6,3))
    stopRequested = db.BooleanProperty(default=False)
    deleteRequested = db.BooleanProperty(default=False)

class Message(db.Model):
    date = db.DateTimeProperty(auto_now_add=True)
    comment = db.TextProperty()
    response = db.TextProperty()
    handle =  db.StringProperty()
    image = db.BlobProperty(default='')
    attachment = db.BlobProperty(default='')
    deleteRequested = db.BooleanProperty(default=False)

def textfromdate(date):
    return date.isoformat()[0:10]

class MainHandler(webapp.RequestHandler):

    def get(self):
        skillName_id = self.request.get("skillName", None)
        user = users.get_current_user()
        if skillName_id is None: #no skillName has been set by the user
            path = os.path.join(os.path.dirname(__file__), 'choose_name.html')
            if user: #offer user or nonuser options back at choose.html
                url = users.create_logout_url(self.request.uri)
                url_linktext = 'Signout'
                url_linktextmore = ' if you wish. You will be returned to this page after you signout.'
            else:
                url = users.create_login_url(self.request.uri)
                url_linktext = 'Signin'
                url_linktextmore = ' if you will be creating a page. You will be returned to this page after you signin.'
            template_values = {
                'url': url,
                'url_linktext': url_linktext,
                'url_linktextmore': url_linktextmore,
                }
            self.response.out.write(template.render(path, template_values))
        else: #some skillName has been set by the person (may be user)
            #so pull up information on the skillName set by the person
            key = db.Key.from_path("Person", skillName_id)
            person = Person.get(key)
            #determine if skillName exists already
            #because choose_name.html has produced a desired skillName
            #or because user has supplied a skillName with ?...
            nowyear = datetime.datetime.now().year
            nowyear0 = nowyear
            nowyear1 = nowyear+1 
            nowyear2 = nowyear+2
            years = [nowyear0, nowyear1, nowyear2]
            #months = [1,2,3,4,5,6,7,8,9,10,11,12] 
            months = []
            for i in range (1,13):
                months += [i]
            days= []
            for i in range (1,32):
                days += [i]
            if person: #person's skillName DOES exist already
                if user and user == person.user: #user is owner and may revise the existing page
                    address = user.email()
                    if person.address is None:
                        person.address = address
                    date = person.stopDate
                    if person.stopRequested:
                        stopRequested = 'stop'
                    else:
                        stopRequested = 'nostop'
                    template_values = dict(skillName_id=person.key(), 
                        skillName=person.skillName, 
                        realName=person.realName, moreinfo=person.moreinfo,
                        purpose=person.purpose, replyinfo=person.replyinfo,
                        whoami=person.whoami, title=person.title,
                        imagecaption=person.imagecaption,
                        years = years,
                        months = months,
                        days = days,
                        yearset = date.year,
                        monthset = date.month,
                        dayset = date.day,
                        address=person.address,
                        stopRequested=stopRequested,
                        activity=person.activity, user=person.user)
                    path = os.path.join(os.path.dirname(__file__), 'add_person.html')
                    self.response.out.write(template.render(path, template_values))
                else: #is not the user so may send to choose with appropos message
                    if user: #offer user or nonuser options back at choose.html
                        url = users.create_logout_url(self.request.uri)
                        url_linktext = 'Signout'
                        url_linktextmore = ' You are not the owner of this page; perhaps you entered the name incorrectly.'
                        template_values = {
                            'url': url,
                            'url_linktext': url_linktext,
                            'url_linktextmore': url_linktextmore,
                            }
                        path = os.path.join(os.path.dirname(__file__),
                                            'choose_name.html')
                        self.response.out.write(template.render(path, template_values))
                    else: 
                        req = person.stopRequested
                        stopDate = textfromdate(person.stopDate)
                        now = textfromdate(datetime.datetime.now())
                        stop = stopDate>now
                        if req and stop:
                            reply = """
<html><pre>
Thank you for your attempt to 
communicate with me. As chance
would have it, I am unavailable 
until %s, so please try again then.
I look forward to hearing from you.

%s
</pre>
</html>
""" % (stopDate, person.realName)
                            self.response.out.write(reply)
                        else: #send respondent to howsmy.html
                            date = person.stopDate
                            template_values = dict(skillName_id=person.key(), 
                                skillName=person.skillName, 
                                realName=person.realName, moreinfo=person.moreinfo,
                                purpose=person.purpose, replyinfo=person.replyinfo,
                                whoami=person.whoami, title=person.title,
                                imagecaption=person.imagecaption,
                                address=person.address,
                                nowyear = datetime.datetime.now().year,
                                years = years,
                                months = months,
                                days = days,
                                year = date.year,
                                month = date.month,
                                day = date.day,
                                stopRequested=person.stopRequested,
                                activity=person.activity, user=person.user)
                            path = os.path.join(os.path.dirname(__file__), 'howsmy.html')
                            self.response.out.write(template.render(path, template_values))
            else: #person's skillName does NOT exist in datastore
                if user: #user needs to create the page 
                    person= Person(key_name=skillName_id)
                    person.skillName = skillName_id
                    person.user = user
                    address = user.email()
                    if person.address is None:
                        person.address = address
                    person.put()
                    date = person.stopDate
                    template_values = dict(skillName_id=person.key(), 
                        skillName=person.skillName, 
                        realName=person.realName, moreinfo=person.moreinfo,
                        address=person.address,
                        purpose=person.purpose, replyinfo=person.replyinfo,
                        whoami=person.whoami, title=person.title,
                        imagecaption=person.imagecaption,
                        nowyear = datetime.datetime.now().year,
                        years = years,
                        months = months,
                        days = days,
                        year = date.year,
                        month = date.month,
                        day = date.day,
                        stopRequested=person.stopRequested,
                        activity=person.activity, user=person.user)
                    path = os.path.join(os.path.dirname(__file__), 'add_person.html')
                    self.response.out.write(template.render(path, template_values))
                else: #send nonuser back to choose.html
                    url = users.create_login_url(self.request.uri)
                    url_linktext = 'Signin'
                    url_linktextmore = ' if you will be creating a page. You will be returned to this page after you signin. <b> You may have mispelled your page. </b>'
                    template_values = {
                        'url': url,
                        'url_linktext': url_linktext,
                        'url_linktextmore': url_linktextmore,
                        }
                    path = os.path.join(os.path.dirname(__file__), 'choose_name.html')
                    self.response.out.write(template.render(path, template_values))

class AddPerson(webapp.RequestHandler):
    def post(self):
        skillName_id = self.request.get('skillName')
        key = db.Key.from_path("Person", skillName_id)
        person = Person.get(key)
        person.realName = self.request.get('realName') 
        person.address = self.request.get('address') 
        person.activity = self.request.get('activity') 
        person.whoami = self.request.get('whoami') 
        person.title = self.request.get('title') 
        person.purpose = self.request.get('purpose') 
        person.moreinfo = self.request.get('moreinfo') 
        person.replyinfo = self.request.get('replyinfo') 
        person.imagecaption = self.request.get('imagecaption') 
        year = int(self.request.get('year'))
        month = int(self.request.get('month'))
        day = int(self.request.get('day') )
        stopRequested = self.request.get('stopRequested') 
        person.stopRequested = False
        if stopRequested == "stop":
            person.stopRequested = True
            person.stopDate = datetime.date(year,month,day)
        person.put()
        self.redirect("/?skillName=%s" % skillName_id)

def word_wrap(string, width=80, ind1=0, ind2=0, prefix=''):
    """ word wrapping function.
        string: the string to wrap
        width: the column number to wrap at
        prefix: prefix each line with this string (goes before any indentation)
        ind1: number of characters to indent the first line
        ind2: number of characters to indent the rest of the lines
    """
    string = prefix + ind1*" " + string
    newstring = ""
    if len(string) > width:
        while True:
            # find position of nearest whitespace char to the left of "width"
            marker = width-1
            while not string[marker].isspace():
                marker = marker - 1

            # remove line from original string and add it to the new string
            newline = string[0:marker] + "\n"
            newstring = newstring + newline
            string = prefix + ind2*" " + string[marker+1:]

            # break out of loop when finished
            if len(string) <= width:
                break
    
    return newstring + string

class ReadReply(webapp.RequestHandler):
    def post(self):
        skillName_id = self.request.get('skillName')
        user = users.get_current_user()
        handle = self.request.get('handle')
        response = self.request.get('response')
        key = db.Key.from_path("Person", skillName_id)
        person = Person.get(key)
        message = Message.get_by_key_name(handle, parent=key)
        message.response = response 
        #message.response = word_wrap(response,60) 
        message.put()
        reply = """
<html><pre>
%s, thank you for your message below to 
me, %s. 

Message:
%s

I have the following reply.
%s
</pre>
</html>
""" % (handle, person.realName, message.comment, response)
        self.response.out.write(reply)
        
    def get(self):
        skillName_id = self.request.get('skillName')
        user = users.get_current_user()
        handle = self.request.get('handle')
        key = db.Key.from_path("Person", skillName_id)
        person = Person.get(key)
        message = Message.get_by_key_name(handle, parent=key)
        response = message.response
        reply = """
<html><pre>
%s, thank you for your message below to %s. 

Message:
%s

%s has the following reply.
%s
</pre>
</html>
""" % (handle, person.realName, message.comment, person.realName, response)
        self.response.out.write(reply)
        
class SaveReply(webapp.RequestHandler):
    def get(self):
        skillName_id = self.request.get('skillName')
        user = users.get_current_user()
        handle = self.request.get('handle')
        key = db.Key.from_path("Person", skillName_id)
        person = Person.get(key)
        message = Message.get_by_key_name(handle, parent=key)
        if user and user == person.user: #user is owner and may reply
            template_values = dict(skillName_id=person.key(), 
                handle = handle,
                comment = message.comment,
                response = message.response,
                skillName=person.skillName, 
                realName=person.realName, 
                title=person.title,
                user=person.user)
            path = os.path.join(os.path.dirname(__file__), 'save.html')
            self.response.out.write(template.render(path, template_values))
        else:
            self.response.out.write("Some error occurred")
            

class SendMessage(webapp.RequestHandler):
    def post(self):
        skillName_id = self.request.get('skillName')
        handle = self.request.get('handle')
        comment = self.request.get('comment')
        key = db.Key.from_path("Person", skillName_id)
        person = Person.get(key)
        user_address = person.address
        sender_address = person.address
        subject = person.title
        message = Message(key_name=handle, parent=key)
        message.comment = comment
        message.handle = handle
        message.response = ''
        body = comment
        response = """
<html><pre>
Thank you for your message below to %s. 

Because you did not offer a handle, %s 
cannot reply to you. Consider supplying 
a handle another time.

Message:
%s
</pre>
</html>
""" % (person.realName , person.realName , comment)
        if handle != '':
            message.put()
            temp = "Handle: ",handle,"\n\n",body
            body = "".join(temp)
            temp = body,"\n\nhttp://tellmestraight.appspot.com/save?skillName=%s&handle=%s"
            body = "".join(temp)
            body = str(body) % (person.skillName, handle  )
            response = """
<html>
<pre>
Thank you for your message below to %s. 

Your message:
%s

</pre>
<hr>
<pre>
Replying information:
When I reply, you can see my reply at
the following link. To make sure you 
remember the link accurately, please go there 
now and even if you get an error, attempt to
bookmark the page in your browser.

Thanks,
%s
</pre>
<hr>
<a href="http://tellmestraight.appspot.com/read?skillName=%s&handle=%s">
http://tellmestraight.appspot.com/read?skillName=%s&handle=%s
</a>
</html>
""" % (person.realName , comment, person.realName , person.skillName , handle, person.skillName, handle  )
        mail.send_mail(sender_address, user_address, subject, str(body))
        self.response.out.write(response)

application = webapp.WSGIApplication([('/', MainHandler),
                                ('/add_person', AddPerson),
                                ('/save', SaveReply),
                                ('/read', ReadReply),
                                ('/message', SendMessage)],
                                debug=True)

def main():
    run_wsgi_app(application)


if __name__ == '__main__':
  main()
